from copy import deepcopy
import numpy as np
import pandas as pd
import random

# 从文件中读取数据
data = pd.read_csv('iris.csv')
c1 = data['slength'].values
c2 = data['swidth'].values
c3 = data['plength'].values
c4 = data['pwidth'].values
X = np.array(list(zip(c1, c2, c3, c4)))

k = 3  # 聚类数（在示例数据中为3）

# 初始化聚类中心，这里使用前三个数据点作为初始中心
c1 = [X[0][0], X[1][0], X[2][0]]
c2 = [X[0][1], X[1][1], X[2][1]]
c3 = [X[0][2], X[1][2], X[2][2]]
c4 = [X[0][3], X[1][3], X[2][3]]
c = np.array(list(zip(c1, c2, c3, c4)), dtype=np.float32)
print("初始聚类中心:\n", c)


# 定义计算两点距离的函数
def dist(a, b, ax=1):
    return np.linalg.norm(a - b, axis=ax)


# 用于存储旧的聚类中心，初始化为零向量
c_old = np.zeros(c.shape)
# 用于存储每个点所属的聚类
clusters = np.zeros(len(X))
# 存储当前迭代的误差，迭代直到误差为零
error = dist(c, c_old, None)

while error != 0:
    # 将每个点分配到最近的聚类
    for i in range(len(X)):
        distances = dist(X[i], c)
        cluster = np.argmin(distances)
        clusters[i] = cluster

    # 保存旧的聚类中心
    c_old = deepcopy(c)

    # 计算每个聚类的新均值
    for i in range(k):
        points = [X[j] for j in range(len(X)) if clusters[j] == i]
        c[i] = np.mean(points, axis=0)

    # 计算新的误差
    error = dist(c, c_old, None)

print("\n最终聚类中心:\n", c)
print("每个样本所属聚类:\n", clusters)
print("最终误差:", error)
